<?php
/******************************
 * EQdkp
 * Copyright 2002-2003
 * Licensed under the GNU GPL.  See COPYING for full terms.
 * ------------------
 * eqdkp.php
 * begin: Sat December 21 2002
 *
 * $Id: eqdkp.php 541 2008-05-20 06:56:16Z rspeicher $
 *
 ******************************/

/**
* EQdkp Class
*
* Adds logging capability throughout the site
* and can be used to cleanly alternate row classes
*
*/

class EQdkp
{
    /**
    * Log table fields
    * @var table_fields
    */
    var $table_fields = array('log_id', 'log_date', 'log_type', 'log_action', 'log_ipaddress', 'log_sid', 'log_result', 'admin_id');

    /**
    * Alternating row class
    * @var row_class
    */
    var $row_class = 'row1';

    /**
    * Contains all configuration settings
    * @var config
    */
    var $config = array();

    /**
    * Constructor
    *
    * Re-assigns the table_fields if provided
    *
    * @param $table_fields Array of log table fields
    */
    function eqdkp($table_fields = array())
    {
        if ( sizeof($table_fields) > 0 )
        {
            $this->table_fields = $table_fields;
        }

        $this->config();
    }

    /**
    * Inserts a log into the database
    *
    * @param $values Array of values
    * @return bool
    */
    function log_insert($values = array())
    {
        global $db;

        if (sizeof($values) > 0)
        {
            $values['log_id'] = ( isset($values['log_id']) ) ? $values['log_id'] : 'NULL';
            $values['log_date'] = ( isset($values['log_date']) ) ? $values['log_date'] : time();

            $fields = '';
            $query_values = '';
            $separator = '';

            foreach ( $values as $k => $v )
            {
                if ( in_array($k, $this->table_fields) )
                {
                    // Take the newlines and tabs (or spaces > 1) out of the action
                    if ( $k == 'log_action' )
                    {
                        $v = preg_replace("/[[:space:]]{2,}/", '', $v);
                        $v = str_replace("\t", '', $v);
                        $v = str_replace("\n", '', $v);
                    }
                    $fields .= $separator.$k;
                    $query_values .= $separator . "'" . addslashes($v) . "'";
                    $separator = ', ';
                }
            }

            $sql = 'INSERT INTO ' . LOGS_TABLE . '
                    (' . $fields . ')
                    VALUES (' . $query_values . ')';
            $db->query($sql);

            return true;
        }
        return false;
    }

    /**
    * Makes a string with an array declaration in it
    * to be eval()'d later
    *
    * @param $action Actual array
    * @return string String array
    */
    function make_log_action($action = array())
    {
        $str_action = "\$log_action = array(";
        foreach ( $action as $k => $v )
        {
            $str_action .= "'" . $k . "' => '" . $v . "',";
        }
        $action = substr($str_action, 0, strlen($str_action)- 1) . ");";
        
        return $action;
    }

    /**
    * Switches the alternate row class
    * 
    * @param $set_new Set the class var to the new row_class?
    * @return string Alternate row
    */
    function switch_row_class($set_new = true)
    {
        $row_class = ( $this->row_class == 'row1' ) ? 'row2' : 'row1';

        if ( $set_new )
        {
            $this->row_class = $row_class;
        }

        return $row_class;
    }

    /**
    * Sets up the $this->config array that contains all configuration variables
    *
    * @return bool
    */
    function config()
    {
        global $db;

        $sql = 'SELECT config_name, config_value
                FROM ' . CONFIG_TABLE;

        if ( !($result = $db->query($sql)) )
        {
            die('Could not obtain configuration information');
        }
        while ( $row = $db->fetch_record($result) )
        {
            $this->config[$row['config_name']] = $row['config_value'];
        }

        return true;
    }
}

/**
* Session class
*
* Manages sessions; Based on phpBB
*/
class Session
{
    /**
    * Session ID
    * @var session_id
    */
    var $session_id = '';

    /**
    * Session data
    * @var data
    */
    var $data = array();

    /**
    * User agent
    * @var browser
    */
    var $browser = '';

    /**
    * User IP
    * @var ip
    */
    var $ip = '';

    /**
    * Current page URL
    * @var page
    */
    var $page = '';

    /**
    * Starts a new session or recovers an existing one
    *
    * @param $update Update session db row
    * @return bool session_start()
    */
    function start($update = true)
    {
        global $SID, $db, $eqdkp;

        // Try and get rid of trans-sid
        @ini_set('session.use_trans_sid', '0');

        $current_time = time();
        $this->browser = ( !empty($_SERVER['HTTP_USER_AGENT']) ) ? $_SERVER['HTTP_USER_AGENT'] : $_ENV['HTTP_USER_AGENT'];
        $this->page  = ( !empty($_SERVER['PHP_SELF']) ) ? $_SERVER['PHP_SELF'] : $_ENV['PHP_SELF'];
        $this->page .= '?' . ( !empty($_SERVER['QUERY_STING']) ) ? $_SERVER['QUERY_STRING'] : $_ENV['QUERY_STRING'];

        // Check for a cookie'd data
        if ( (isset($_COOKIE[$eqdkp->config['cookie_name'] . '_sid'])) || (isset($_COOKIE[$eqdkp->config['cookie_name'] . '_data'])) )
        {
            $session_data = ( isset($_COOKIE[$eqdkp->config['cookie_name'] . '_data']) ) ? unserialize(stripslashes($_COOKIE[$eqdkp->config['cookie_name'] . '_data'])) : '';
            $this->session_id = ( isset($_COOKIE[$eqdkp->config['cookie_name'] . '_sid']) ) ? $_COOKIE[$eqdkp->config['cookie_name'] . '_sid'] : '';
            $SID = ( defined('IN_ADMIN') ) ? '?' . URI_SESSION . '='.$this->session_id : '?' . URI_SESSION . '=';
        }
        // Try and get the SID from the URI
        else
        {
            $session_data = array();
            $this->session_id = ( isset($_GET[URI_SESSION]) ) ? $_GET[URI_SESSION] : '';
            $SID = '?' . URI_SESSION .'='.$this->session_id;
        }

        // Obtain users IP, used in uniqid() to get a session_id
        $this->ip = ( !empty($_SERVER['REMOTE_ADDR']) ) ? $_SERVER['REMOTE_ADDR'] : $REMOTE_ADDR;

        if ( !empty($_SERVER['HTTP_X_FORWARDED_FOR']) )
        {
            if ( preg_match('/^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/', $_SERVER['HTTP_X_FORWARDED_FOR'], $ip_list) )
            {
                $private_ip = array('/^0\./', '/^127\.0\.0\.1/', '/^192\.168\..*/', '/^172\.16\..*/', '/^10\..*/', '/^224\..*/', '/^240\..*/');
                $this->ip = preg_replace($private_ip, $this->ip, $ip_list[1]);
            }
        }

        // If session id isn't empty, we can grab the data for it
        if ( !empty($this->session_id) )
        {
            $sql = 'SELECT u.*, s.*
                    FROM ' . SESSIONS_TABLE . ' s, ' . USERS_TABLE . " u
                    WHERE s.session_id='" . $this->session_id . "'
                    AND u.user_id=s.session_user_id";
            $result = $db->query($sql);

            $this->data = $db->fetch_record($result);
            $db->free_result($result);

            // Check if the session existed in the DB
            if ( isset($this->data['user_id']) )
            {
                // Validate IP length according to admin ... has no effect on IPv6
                $session_ip = implode('.', array_slice(explode('.', $this->data['session_ip']), 0, 4));
                $user_ip = implode('.', array_slice(explode('.', $this->ip), 0, 4));

                if ( $user_ip == $session_ip )
                {
                   // Update the session DB ~1 min after last update or if page changes
                    if ( (($current_time - $this->data['session_current'] > 60) || ($this->data['session_page'] != $this->page)) && ($update) )
                    {
                        $sql = 'UPDATE ' . SESSIONS_TABLE . "
                                SET session_current='".$current_time."', session_page='".$this->page."'
                                WHERE session_id='".$this->session_id."'";
                        $db->query($sql);
                    }
                    return true;
                }
            }
        }

        // At this point no valid session exists, so we'll create a new one,
        // using the cookie user_id (if available) to pull basic user preferences.
        $auto_login = ( isset($session_data['auto_login_id']) ) ? $session_data['auto_login_id'] : '';
        $user_id = ( isset($session_data['user_id']) ) ? intval($session_data['user_id']) : ANONYMOUS;

        return $this->create($user_id, $auto_login);
    }

    /**
    * Create/update a session
    *
    * @param $user_id User ID
    * @param $auto_login Auto-login or not
    * @param $set_auto_login Set auto_login value or not
    * @return bool
    */
    function create(&$user_id, &$auto_login, $set_auto_login = false)
    {
        global $SID, $db, $eqdkp;
        global $user_ip;

        $session_data = array();
        $current_time = time();

        // Remove old sessions and update user information if necessary.
        if ( $current_time - $eqdkp->config['session_cleanup'] > $eqdkp->config['session_last_cleanup'] )
        {
            $this->cleanup($current_time);
        }

        // Grab user data
        $sql = 'SELECT u.*, s.session_current
                FROM ( ' . USERS_TABLE . ' u
                LEFT JOIN ' . SESSIONS_TABLE . ' s
                ON s.session_user_id=u.user_id )
                WHERE u.user_id = '.$user_id. '
                ORDER BY s.session_current DESC';
        $result = $db->query($sql);

        $this->data = $db->fetch_record($result);
        $db->free_result($result);

        // Check auto_login request to see if it's valid
        if ( (empty($this->data) || (($this->data['user_password'] != $auto_login) && (!$set_auto_login))) )
        {
            $auto_login = '';
            $this->data['user_id'] = $user_id = ANONYMOUS;
        }

        // If there's an existing session, grab last visit time from that
        $this->data['session_last_visit'] = ( isset($this->data['session_current']) ) ? $this->data['session_current'] :
            ( (isset($this->data['user_lastvisit'])) ? $this->data['user_lastvisit'] : time());

        // Create or update the session
        $sql = 'UPDATE ' . SESSIONS_TABLE . "
                SET session_user_id='".$user_id."', session_last_visit='".$this->data['session_last_visit']."', session_start='".$current_time."', session_page='".$this->page."'
                WHERE session_id='".$this->session_id."'";

        // If nothing happened from the UPDATE query, insert a new session
        if ( (!$db->query($sql)) || (!$db->affected_rows()) )
        {
            $this->session_id = md5(uniqid($user_ip));

            $sql = 'INSERT INTO ' . SESSIONS_TABLE . "
                    (session_id, session_user_id, session_last_visit, session_start, session_current, session_page,  session_ip)
                    VALUES ('".$this->session_id."','".$user_id."','".$this->data['session_last_visit']."','".$current_time."','".$current_time."','".$this->page."','".$this->ip."')";
            $db->query($sql);
        }

        $this->data['session_id'] = $this->session_id;

        $session_data['auto_login_id'] = ( ($auto_login) && ($user_id != ANONYMOUS) ) ? $auto_login : '';
        $session_data['user_id'] = $user_id;

        $this->set_cookie('data', serialize($session_data), $current_time + 31536000);
        $this->set_cookie('sid', $this->session_id, 0);
        $SID = '?' . URI_SESSION . '='.$this->session_id;

        return true;
    }

    /**
    * Destroy a session
    *
    * @return bool
    */
    function destroy()
    {
        global $SID, $db, $eqdkp;

        $current_time = time();

        $this->set_cookie('data', '', $current_time - 31536000);
        $this->set_cookie('sid', '', $current_time - 31536000);
        $SID = '?' . URI_SESSION . '=';

        // Update last visit info and delete existing session
        $sql = 'UPDATE ' . USERS_TABLE . "
                SET user_lastvisit='".intval($this->data['session_current']) . "'
                WHERE user_id='".$this->data['user_id']."'";
        $db->query($sql);

        $sql = 'DELETE FROM ' . SESSIONS_TABLE . "
                WHERE session_id='".$this->session_id."'
                AND session_user_id='".$this->data['user_id']."'";
        $db->query($sql);

        $this->session_id = '';

        return true;
    }

    /**
    * Garbage collection
    *
    * @param $current_time
    * @return void
    */
    function cleanup(&$current_time)
    {
        global $db, $eqdkp;

        // Get most recent expired session for each user
        $sql = 'SELECT session_user_id, MAX(session_current) AS recent_time
                FROM ' . SESSIONS_TABLE . "
                WHERE session_current < ".($current_time - $eqdkp->config['session_length'] ) . '
                GROUP BY session_user_id
                LIMIT 5';
        $result = $db->query($sql);

        // Build a delete query
        $del_user_id = '';
        $del_sessions = 0;

        while ( $row = $db->fetch_record($result) )
        {
            if ( $row['session_user_id'] )
            {
                $sql = 'UPDATE ' . USERS_TABLE . "
                        SET user_lastvisit='".$row['recent_time']."'
                        WHERE user_id='".$row['session_user_id']."'";
                $db->query($sql);
            }

            $del_user_id .= ( ($del_user_id != '') ? ', ' : '') . ' \'' . $row['session_user_id'] . '\'';
            $del_sessions++;
        }

        if ( $del_user_id != '' )
        {
            // Delete the expired sessions
            $sql = 'DELETE FROM ' . SESSIONS_TABLE . '
                    WHERE session_user_id IN ('.$del_user_id.')
                    AND session_current < '.($current_time - $eqdkp->config['session_length']);
            $db->query($sql);
        }

        if ( $del_sessions < 5 )
        {
            // Less than 5 sessions, update gc timer
            // Otherwise we want cleanup called again to delete other sessions
            $sql = 'UPDATE ' . CONFIG_TABLE . "
                    SET config_value='".$current_time."'
                    WHERE config_name='session_last_cleanup'";
            $db->query($sql);
        }

        return;
    }

    /**
    * Sets a cookie
    *
    * @param $name Cookie name
    * @param $cookie_data Cookie Data
    * @param $cookie_time Cookie expiration time
    */
    function set_cookie($name, $cookie_data, $cookie_time)
    {
        global $eqdkp;

        setcookie($eqdkp->config['cookie_name'] . '_' . $name, $cookie_data, $cookie_time, $eqdkp->config['cookie_path'], $eqdkp->config['cookie_domain']);
    }
}

/**
* User Class
*
* Stores user/global preferences
* and language data
*/

class User extends Session
{
    /**
    * Language array
    * @var lang
    */
    var $lang = array();

    /**
    * Language set name
    * @var lang_name
    */
    var $lang_name;

    /**
    * Language path
    * @var lang_path
    */
    var $lang_path;

    /**
    * Style/theme settings
    * @var style
    */
    var $style = array();

    /**
    * Sets up user language and style settings
    *
    * @param $lang_set Language to set
    * @param $style Style ID to set
    */
    function setup($lang_set = false, $style = false)
    {
        global $db, $eqdkp, $eqdkp_root_path, $tpl;

        // Set up language array
        if ( (isset($this->data['user_id'])) && ($this->data['user_id'] != ANONYMOUS) && (!empty($this->data['user_lang'])) )
        {
            $this->lang_name = ( file_exists($eqdkp_root_path . 'language/' . $this->data['user_lang']) ) ? $this->data['user_lang'] : $eqdkp->config['default_lang'];
            $this->lang_path = $eqdkp_root_path . 'language/' . $this->lang_name . '/';
        }
        else
        {
            $this->lang_name = $eqdkp->config['default_lang'];
            $this->lang_path = $eqdkp_root_path . 'language/' . $this->lang_name . '/';
        }

        include($this->lang_path . 'lang_main.php');
        if ( defined('IN_ADMIN') )
        {
            include($this->lang_path . 'lang_admin.php');
        }
        // Get language pack for a plugin, if we're in one
        if ( defined('PLUGIN') )
        {
            $plugin = new EQdkp_Plugin(PLUGIN);
            
            $plugin_lang_file = $eqdkp_root_path . 'plugins/' . $plugin->data['plugin_path'] . '/language/' . $this->lang_name . '/lang_main.php';
            if ( file_exists($plugin_lang_file) )
            {
                include($plugin_lang_file);
            }
            
            unset($plugin);
        }
        
        $this->lang = &$lang;

        // Set up style
        $style = ( $style ) ? $style : ( ($this->data['user_id'] != ANONYMOUS) ? $this->data['user_style'] : $eqdkp->config['default_style']);

        $sql = 'SELECT s.*, c.*
                FROM ' . STYLES_TABLE . ' s, ' . STYLES_CONFIG_TABLE . ' c
                WHERE s.style_id=c.style_id
                AND s.style_id='.$style;
        $result = $db->query($sql);

        if ( !($this->style = $db->fetch_record($result)) )
        {
            // If we STILL can't get style information, go back to the default
            // Fail-safe in case someone (ahem) forgets to add style config settings
            $sql = 'SELECT s.*, c.*
                    FROM ' . STYLES_TABLE . ' s, ' . STYLES_CONFIG_TABLE . ' c
                    WHERE s.style_id=c.style_id
                    AND s.style_id='.$eqdkp->config['default_style'];
            $result = $db->query($sql);
            $this->style = $db->fetch_record($result);
        }

        $tpl->set_template($this->style['template_path']);

        // Default the limits if the user's anonymous
        if ( $this->data['user_id'] == ANONYMOUS )
        {
            $this->data['user_alimit'] = $eqdkp->config['default_alimit'];
            $this->data['user_elimit'] = $eqdkp->config['default_elimit'];
            $this->data['user_ilimit'] = $eqdkp->config['default_ilimit'];
            $this->data['user_nlimit'] = $eqdkp->config['default_nlimit'];
            $this->data['user_rlimit'] = $eqdkp->config['default_rlimit'];
        }
        
        //
        // Permissions
        //
        $this->data['auth'] = array();
        if ( $this->data['user_id'] == ANONYMOUS )
        {
            // Get the default permissions if they're not logged in
            $sql = 'SELECT auth_value, auth_default AS auth_setting
                    FROM ' . AUTH_OPTIONS_TABLE;
        }
        else
        {
            $sql = 'SELECT o.auth_value, u.auth_setting
                    FROM ' . AUTH_USERS_TABLE . ' u, ' . AUTH_OPTIONS_TABLE . " o
                    WHERE (u.auth_id = o.auth_id)
                    AND (u.user_id='".$this->data['user_id']."')";
        }
        if ( !($result = $db->query($sql)) )
        {
            die('Could not obtain permission data');
        }
        while ( $row = $db->fetch_record($result) )
        {
            $this->data['auth'][$row['auth_value']] = $row['auth_setting'];
        }

        return;
    }
    
    /**
    * Checks if a user has permission to do ($auth_value)
    * 
    * @param $auth_value Permission we want to check (may be RegEx if $exact is set to false
    * @param $die If they don't have permission, exit with message_die or just return false?
    * @return bool
    */
    function check_auth($auth_value, $die = true, $user_id = 0)
    {
        // Look up a specific user if an id was provided...otherwise we're going to
        // use the $this->data['auth'] array
        if ( intval($user_id) > 0 )
        {
            global $db;
            
            $sql = 'SELECT au.auth_setting, ao.auth_value
                    FROM ' . AUTH_USERS_TABLE . ' au, ' . AUTH_OPTIONS_TABLE . " ao
                    WHERE (au.auth_id = ao.auth_id) AND (au.user_id='".$user_id."')";
            $result = $db->query($sql);
            while ( $row = $db->fetch_record($result) )
            {
                $auth[$row['auth_value']] = $row['auth_setting'];
            }
            $db->free_result($result);
        }
        else
        {
            $auth = $this->data['auth'];
        }
        
        if ( (!isset($auth)) || (!is_array($auth)) )
        {
            return ( $die ) ? message_die($this->lang['noauth_default_title'], $this->lang['noauth_default_title']) : false;
        }
        
        // If auth_value ends with a '_' it's checking for any permissions of that type
        $exact = ( strrpos($auth_value, '_') == (strlen($auth_value) - 1) ) ? false : true;
        
        foreach ( $auth as $value => $setting )
        {
            if ( $exact )
            {
                if ( ($value == $auth_value) && ($setting == 'Y') )
                {
                    return true;
                }
            }
            else
            {
                if ( preg_match('/^('.$auth_value.'.+)$/', $value, $match) )
                {
                    if ( $auth[$match[1]] == 'Y' )
                    {
                        return true;
                    }
                }
            }
        }
        
        $index = ( $exact ) ? $auth_value : 'default_title';
        
        return ( $die ) ? message_die($this->lang['noauth_'.$index], $this->lang['noauth_default_title']) : false;
    }

    /**
    * Attempt to log in a user
    *
    * @param $username
    * @param $password
    * @param $auto_login Save login in cookie?
    * @return bool
    */
    function login($username, $password, $auto_login)
    {
        global $user, $db, $eqdkp;

        $sql = 'SELECT user_id, username, user_password, user_email, user_active
                FROM ' . USERS_TABLE . "
                WHERE username='".remove_quote_escape($username)."'";
        $result = $db->query($sql);

        if ( $row = $db->fetch_record($result) )
        {
            $db->free_result($result);

            if ( (md5($password) == $row['user_password']) && ($row['user_active']) )
            {
                $auto_login = ( !empty($auto_login) ) ? md5($password) : '';

                return $this->create($row['user_id'], $auto_login, true);
            }
        }
        return false;
    }
}

/**
* Plugin Management Class
*/
class EQdkp_Plugin
{
    /**
    * Available plugins
    * @var plugins
    */
    var $plugins = array();
    
    /**
    * Plugin data
    * @var data
    */
    var $data = array();
    
    /**
    * Plugin's template directory
    * @var template_dir
    */
    var $template_dir = '';
    
    /**
    * Constructor
    * 
    * Either sets up our $plugins array or calls _init
    * to set up the data array for a specific plugin
    * 
    * @param $plugin_code Specific plugin to init
    */
    function eqdkp_plugin($plugin_code = '')
    {
        // If a specific plugin wasn't provided, we're just getting
        // data for our installed plugins and including their setup
        // files so we have their hooks and constants
        if ( empty($plugin_code) )
        {
            global $db, $user, $eqdkp_root_path, $table_prefix;
            global $eqdkp_hooks;
        
            $sql = 'SELECT plugin_id, plugin_code, plugin_path
                    FROM ' . PLUGINS_TABLE . "
                    WHERE plugin_installed='1'";
            $result = $db->query($sql);
            while ( $row = $db->fetch_record($result) )
            {
                $this->plugins[$row['plugin_id']] = $row['plugin_code'];
                
                @include_once($eqdkp_root_path . 'plugins/' . $row['plugin_path'] . '/setup.php');
                
                // Language
                @include_once($eqdkp_root_path . 'plugins/' . $row['plugin_path'] . '/language/' . $user->lang_name . '/lang_main.php');
                if ( @is_array($lang) )
                {
                    $user->lang = array_merge($user->lang, $lang);
                }
                $this->_init($row['plugin_code']);
            }
        }
        else
        {
            $this->_init($plugin_code);
        }
    }
    
    /**
    * Sets up data for a specific plugin
    * 
    * @param $plugin_code
    */
    function _init($plugin_code)
    {
        global $db, $eqdkp_root_path, $table_prefix;
        
        $sql = 'SELECT *
                FROM ' . PLUGINS_TABLE . "
                WHERE plugin_code='".$plugin_code."'";
        $result = $db->query($sql);
        $plugin_data = $db->fetch_record($result);
        
        $this->data = $plugin_data;
        
        $this->template_dir = 'plugins/' . $this->data['plugin_code'] . '/templates/';
        
        $setup_file = $eqdkp_root_path . 'plugins/' . $this->data['plugin_path'] . '/setup.php';
        if ( file_exists($setup_file) )
        {
            include_once($setup_file);
            $function = 'eqdkp_plugin_init_'.$plugin_code;
            if ( function_exists($function) )
            {
                $function();
            }
        }
    }
    
    /**
    * Sees is a plugin is installed
    * 
    * @return bool
    */
    function is_installed()
    {
        if ( (empty($this->data['plugin_installed'])) || ($this->data['plugin_installed'] == '0') )
        {
            return false;
        }
        return true;
    }
}

/**
* Form Validate Class
* Validates various elements of a form and types of data
*/
class Form_Validate
{
    /**
    * Array of errors
    * @var errors
    */
    var $errors = array();

    /**
    * Constructor
    *
    * Initiates the error list
    */
    function form_validate()
    {
        $this->_reset_error_list();
    }

    /**
    * Resets the error list
    *
    * @access private
    */
    function _reset_error_list()
    {
        $this->errors = array();
    }

    /**
    * Returns the array of errors
    *
    * @return array Errors
    */
    function get_errors()
    {
        return $this->errors;
    }

    /**
    * Checks if errors exist
    *
    * @return bool
    */
    function is_error()
    {
        if ( @sizeof($this->errors) > 0 )
        {
            return true;
        }

        return false;
    }

    /**
    * Returns a string with the appropriate error message
    *
    * @param $field Field to generate an error for
    * @return string Error string
    */
    function generate_error($field)
    {
        global $eqdkp_root_path;

        if ( $field != '' )
        {
            if ( !empty($this->errors[$field]) )
            {
                $error = '<br /><img src="'.$eqdkp_root_path . 'images/error.gif"
                          align="middle" alt="Error" />&nbsp;<b>'.
                          $this->errors[$field].'</b>';
                return $error;
            }
            else
            {
                return '';
            }
        }
        else
        {
            return '';
        }
    }

    /**
    * Returns the value of a variable in _POST or _GET
    *
    * @access private
    * @param $field_name Field name
    * @param $from post/get
    * @return mixed Value of the field_name
    */
    function _get_value($field_name, $from = 'post')
    {
        if ( $from == 'post' )
        {
            return ( isset($_POST[$field_name]) ) ? $_POST[$field_name] : false;
        }
        elseif ( $from == 'get' )
        {
            return ( isset($_GET[$field_name]) ) ? $_GET[$field_name] : false;
        }
    }

    // Begin validator methods
    // Note: The validation methods can accept arrays for the $field param
    // in this form: $field['fieldname'] = "Error message";
    // and the validation will be performed on each key/val pair.
    // If an array if used for validation, the method will always return true

    /**
    * Checks if a field is filled out
    *
    * @param $field Field name to check
    * @param $message Error message to insert
    * @return bool
    */
    function is_filled($field, $message = '')
    {
        if ( is_array($field) )
        {
            foreach ( $field as $k => $v )
            {
                $value = $this->_get_value($k);
                if ( trim($value) == '' )
                {
                    $this->errors[$k] = $v;
                }
            }
            return true;
        }
        else
        {
            $value = $this->_get_value($field);
            if ( trim($value) == '' )
            {
                $this->errors[$field] = $message;
                return false;
            }
            return true;
        }
    }

    /**
    * Checks if a field is numeric
    *
    * @param $field Field name to check
    * @param $message Error message to insert
    * @return bool
    */
    function is_number($field, $message = '')
    {
        if ( is_array($field) )
        {
            foreach ( $field as $k => $v )
            {
                $value = $this->_get_value($k);
                if ( !is_numeric($value) )
                {
                    $this->errors[$k] = $v;
                }
            }
            return true;
        }
        else
        {
            $value = $this->_get_value($field);
            if ( !is_numeric($value) )
            {
                $this->errors[$field] = $message;
                return false;
            }
            return true;
        }
    }

    /**
    * Checks if a field is alphabetic
    *
    * @param $field Field name to check
    * @param $message Error message to insert
    * @return bool
    */
    function is_alpha($field, $message = '')
    {
        if ( is_array($field) )
        {
            foreach ( $field as $k => $v )
            {
                $value = $this->_get_value($k);
                if ( !preg_match("/^[a-zA-Z[:space:]]+$/", $value) )
                {
                    $this->errors[$k] = $v;
                }
            }
            return true;
        }
        else
        {
            $value = $this->_get_value($field);
            if ( !preg_match("/^[a-zA-Z[:space:]]+$/", $value) )
            {
                $this->errors[$field] = $message;
                return false;
            }
            return true;
        }
    }

    /**
    * Checks if a field is a valid hexadecimal color code (#FFFFFF)
    *
    * @param $field Field name to check
    * @param $message Error message to insert
    * @return bool
    */
    function is_hex_code($field, $message = '')
    {
        if ( is_array($field) )
        {
            foreach ( $field as $k => $v )
            {
                $value = $this->_get_value($k);
                if ( !preg_match("/(#)?[0-9A-Fa-f]{6}$/", $value) )
                {
                    $this->errors[$k] = $v;
                }
            }
            return true;
        }
        else
        {
            $value = $this->_get_value($field);
            if ( !preg_match("/(#)?[0-9A-Fa-f]{6}$/", $value) )
            {
                $this->errors[$field] = $message;
                return false;
            }
            return true;
        }
    }

    /**
    * Checks if a field is within a minimum and maximum range
    * NOTE: Will NOT accept an array of fields
    *
    * @param $field Field name to check
    * @param $min Minimum value
    * @param $max Maximum value
    * @param $message Error message to insert
    * @return bool
    */
    function is_within_range($field, $min, $max, $message = '')
    {
        $value = $this->_get_value($field);
        if ( (!is_numeric($value)) || ($value < $min) || ($value > $max) )
        {
            $this->errors[$field] = $message;
            return false;
        }
        return true;
    }

    /**
    * Checks if a field has a valid e-mail address pattern
    *
    * @param $field Field name to check
    * @param $message Error message to insert
    * @return bool
    */
    function is_email_address($field, $message = '')
    {
        if ( is_array($field) )
        {
            foreach ( $field as $k => $v )
            {
                $value = $this->_get_value($k);
                if ( !preg_match("/^([a-zA-Z0-9])+([\.a-zA-Z0-9_-])*@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-]+)+/", $value) )
                {
                    $this->errors[$k] = $v;
                }
            }
            return true;
        }
        else
        {
            $value = $this->_get_value($field);
            if ( !preg_match("/^([a-zA-Z0-9])+([\.a-zA-Z0-9_-])*@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-]+)+/", $value) )
            {
                $this->errors[$field] = $message;
                return false;
            }
            return true;
        }
    }

    /**
    *  Checks if a field has a valid IP address pattern
    *
    * @param $field Field name to check
    * @param $message Error message to insert
    * @return bool
    */
    function is_ip_address($field, $message = '')
    {
        if ( is_array($field) )
        {
            foreach ( $field as $k => $v )
            {
                $value = $this->_get_value($k);
                if ( !preg_match("/([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})/", $value) )
                {
                    $this->errors[$k] = $v;
                }
            }
            return true;
        }
        else
        {
            $value = $this->_get_value($field);
            if ( !preg_match("/([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})/", $value) )
            {
                $this->errors[$field] = $v;
                return false;
            }
            return true;
        }
    }

    /**
    * Checks if two fields match eachother exactly
    * Used to verify the password/confirm password fields
    *
    * @param $field Field name to check
    * @param $message Error message to insert
    * @return bool
    */
    function matching_passwords($field1, $field2, $message = '')
    {
        $value1 = $this->_get_value($field1);
        $value2 = $this->_get_value($field2);

        if ( md5($value1) != md5($value2) )
        {
            $this->errors[$field1] = $message;
            return false;
        }
        return true;
    }
}
?>